package com.corejsf;
import java.io.Serializable;

import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

/**
 * This is the user's session data carrying bean.
 *
 * @author Victor Lu
 * @author Vukasin Simic
 * @version 1.0
 */
@SessionScoped
@Named("loginSession")
public class LoginSession implements Serializable {

    /**
     * serialVersionUID.
     */
    private static final long serialVersionUID = 6557439783811001964L;
    /**
     * Manages and authenticates LoginSessions.
     */
    @Inject private UserManager um;
    /**
     * Credentials entered by user on last login attempt.
     */
    @Inject private Credentials credentials;
    /**
     * Authenticated user's user object.
     */
    private User currentUser;

    /**
     * Gets the Scheduler of the logged-in user.
     *
     * @return current logged-in user's Scheduler
     */
    public Scheduler getScheduler() {
        return currentUser.getScheduler();
    }

    /**
     * Gets User object of logged-in user.
     *
     * @return logged-in user's User object
     */
    public User getCurrentUser() {
        return currentUser;
    }

    /**
     * Sets User object corresponding to valid login credentials.
     *
     * @param currentUser logged-in user's User object
     */
    public void setCurrentUser(final User currentUser) {
        this.currentUser = currentUser;
    }

    /**
     * Gets user form input.
     *
     * @return login credentials and form inputs of the user.
     */
    public Credentials getCredentials() {
        return credentials;
    }

    /**
     * Sets user form inputs.
     *
     * @param credentials used by user for last form submit
     */
    public void setCredentials(final Credentials credentials) {
        this.credentials = credentials;
    }

    /**
     * Checks if user passed authentication and successfully logged in.
     *
     * @return whether or not user is currently logged in.
     */
    public boolean isLoggedIn() {
        return (currentUser != null);
    }

    /**
     * Logs user in, if provided credentials are valid.
     *
     * Delegates responsibility to UserManager's login().
     *
     * @return navigation outcome string
     */
    public String login() {
        currentUser = um.login(credentials.getUsername(),
                               credentials.getPassword());

        if (isLoggedIn()) {
            return "valid";
        }
        return "invalid";
    }

    /**
     * Ends user's current session.
     *
     * @return navigation outcome string
     * @link http://stackoverflow.com/questions/5619827/
     *              how-to-invalidate-session-in-jsf-2-0
     */
    public String logout() {
        FacesContext.getCurrentInstance().
                     getExternalContext().invalidateSession();
        return "login";
    }

    /**
     * Checks if user associated with this LoginSession is an Administrator.
     *
     * @return whether or not this user is an Administrator
     */
    public boolean isAdmin() {
        return currentUser.isAdmin();
    }

}
